#include "service.h"
#include <iostream>
#include <thread>
#include <cstring>

Service::Service(const char *addr, int port, int connMax) {
    if(WSAStartup(MAKEWORD(2, 2), &wsaData)) {
        WSACleanup();
        throw "ERROR::调用 WSAStartup() 方法发生错误！\n";
    }
    servSock = socket(AF_INET, SOCK_STREAM, 0);
    servAddr.sin_family = AF_INET;
    servAddr.sin_addr.S_un.S_addr = inet_addr(addr);
    servAddr.sin_port = htons(port);
    if(bind(servSock, (SOCKADDR*)&servAddr, sizeof(servAddr))) {
        WSACleanup();
        closesocket(servSock);
        throw "ERROR::调用 bind() 方法发生错误！\n";
    }
    if(listen(servSock, connMax)) {
        WSACleanup();
        closesocket(servSock);
        throw "ERROR::调用 listen() 方法发生错误！\n";
    }
}

void recvMsg(SOCKET cliSock) {
    char buf[1024] = {0};
    while (true) {
        int nRecv = recv(cliSock, buf, sizeof(buf), 0);
        if(nRecv == SOCKET_ERROR) break;
        if(nRecv > 0) {
            if(!std::strncmp(buf, "quit", 4)) break;
        }
        std::cout<<buf<<'\n';
    }
}

void Service::connAccept() {
    while (true) {
        int addrLen = sizeof(SOCKADDR);
        SOCKET cliSock = accept(servSock, (SOCKADDR*)&servAddr, &addrLen);
        if(cliSock == INVALID_SOCKET) {
            std::cout<<"ERROR::调用 accept() 方法发生错误！\n"<<WSAGetLastError();
            break;
        }
        std::thread t(recvMsg, cliSock);
        t.detach();
        m.lock();
        socketList.push_back(cliSock);
        m.unlock();
    }
}

Service::~Service() {
    WSACleanup();
    closesocket(servSock);
}

void Service::allSend(const char *msg) {
    for (const auto &item : socketList) send(item, msg, sizeof(msg), 0);
}

void Service::monitor() {
    std::thread t(&Service::connAccept, this);
    t.detach();
}


